package phase4Specification.testing;

import phase2Specification.testing.hypeerweb.ExpectedResult;
import dbPhase.hypeerweb.BroadcastVisitor;
import dbPhase.hypeerweb.HyPeerWeb;
import dbPhase.hypeerweb.HyPeerWebDatabase;
import dbPhase.hypeerweb.Node;
import dbPhase.hypeerweb.Parameters;
import dbPhase.hypeerweb.SendVisitor;
import dbPhase.hypeerweb.SimplifiedNodeDomain;

public class SendAndBroadcastTest {
	  public static HyPeerWeb hypeerweb = null;
	  private static final int PHASE_4_Send_TEST_COUNT = 1;
	    private static int errorCount = 0;

	    public static void main(String[] args) {
	        HyPeerWebDatabase.initHyPeerWebDatabase();
	        HyPeerWebDatabase.getSingleton().clear();
	        hypeerweb = HyPeerWeb.getSingleton();
	        testPhase4Send();
	     //   testPhase4Broadcast();
	    }
	    
	    private static void testPhase4Broadcast() {
	    	hypeerweb.clear();
	    	System.out.println("testPhase4Broadcast");
	    	System.out.println("Created Size 8 hypeercube");
	    	createHyPeerWebWith(8);
	    	Node start = hypeerweb.getNode(0);
	    	
	    	BroadcastVisitor broadcastvisitor = new BroadcastVisitor() {	
				@Override
				protected void operation(Node node, Parameters parameters) {
					System.out.println("I am Node "+ node.getWebIdValue()+" and I was visited by broadcast.");
				}
			};

			System.out.println("Node 0 broadcast: Print out I am....");
			Parameters params = BroadcastVisitor.createInitialParameters();
			start.accept(broadcastvisitor, params);
			//-----
			for(int a = 0; a< hypeerweb.size(); a++){
				System.out.println("Contents: secret: " + hypeerweb.getNode(a).contents.get("secret"));
			}
			
			
	    	broadcastvisitor = new BroadcastVisitor() {	
				@Override
				protected void operation(Node node, Parameters parameters) {
					System.out.println("setting my content : secret = source");
					node.contents.set("secret", parameters.get("Source"));
				}
			};

			System.out.println("Node 0 broadcast: set secret in contents to parameters source");
			params = BroadcastVisitor.createInitialParameters();
			start.accept(broadcastvisitor, params);
			
			
			for(int a = 0; a< hypeerweb.size(); a++){
				System.out.println("Contents: secret: " + hypeerweb.getNode(a).contents.get("secret"));
			}
			//--------
			
	    	broadcastvisitor = new BroadcastVisitor() {	
				@Override
				protected void operation(Node node, Parameters parameters) {
					System.out.println("I am Node "+ node.getWebIdValue()+" and I was visited by broadcast.");
				}
			};

			System.out.println("Node 5 broadcast: Print out I am....");
			params = BroadcastVisitor.createInitialParameters();
			hypeerweb.getNode(5).accept(broadcastvisitor, params);
			
			
			hypeerweb.clear();
	    	System.out.println("Created Size 32 hypeercube");
	    	createHyPeerWebWith(32);
			
	    	broadcastvisitor = new BroadcastVisitor() {	
				@Override
				protected void operation(Node node, Parameters parameters) {
					System.out.println("I am Node "+ node.getWebIdValue()+" and I was visited by broadcast.");
				}
			};

			System.out.println("Node 0 broadcast: Print out I am....");
			params = BroadcastVisitor.createInitialParameters();
			hypeerweb.getNode(0).accept(broadcastvisitor, params);
			
			
			hypeerweb.clear();
	    	System.out.println("Created Size 32 hypeercube");
	    	createHyPeerWebWith(32);
			
	    	broadcastvisitor = new BroadcastVisitor() {	
				@Override
				protected void operation(Node node, Parameters parameters) {
					System.out.println("I am Node "+ node.getWebIdValue()+" and I was visited by broadcast.");
				}
			};

			System.out.println("Node 31 broadcast: Print out I am....");
			params = BroadcastVisitor.createInitialParameters();
			hypeerweb.getNode(31).accept(broadcastvisitor, params);
			
			
			
			
			hypeerweb.clear();
	    	System.out.println("Created Size 32 hypeercube");
	    	createHyPeerWebWith(32);
			
	    	broadcastvisitor = new BroadcastVisitor() {	
				@Override
				protected void operation(Node node, Parameters parameters) {
					System.out.println("I am Node "+ node.getWebIdValue()+" and I was visited by broadcast.");
				}
			};

			System.out.println("Node 17 broadcast: Print out I am....");
			params = BroadcastVisitor.createInitialParameters();
			hypeerweb.getNode(17).accept(broadcastvisitor, params);
			
			
			// Try deleting eveyone!!
			
			// set param, dontkillme
			
			
			
		}

		private static void testPhase4Send() {
	    	hypeerweb.clear();
	    	System.out.println("testPhase4Send");
	    	System.out.println("Created Size 32 hypeercube");
	    	createHyPeerWebWith(32);
	    	Node start = hypeerweb.getNode(0);
	    	
	    	SendVisitor sendvisitor = new SendVisitor() {	
				@Override
				protected void targetOperation(Node node, Parameters parameters) {
					System.out.println("I am Node "+ node.getWebIdValue()+" and I was visited by sendvisitor. I should be the target.");
				}
			};

			System.out.println("Node 0 send to node 7: Print out I am....");
			Parameters params = SendVisitor.createInitialParameters(7);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 0 send to node 1: Print out I am....");
			params = SendVisitor.createInitialParameters(1);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 0 send to node 2: Print out I am....");
			params = SendVisitor.createInitialParameters(2);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 0 send to node 3: Print out I am....");
			params = SendVisitor.createInitialParameters(3);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 0 send to node 31: Print out I am....");
			params = SendVisitor.createInitialParameters(31);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 0 send to node 32: Print out WebId....");
			params = SendVisitor.createInitialParameters(32);
			start.accept(sendvisitor, params);
			
			start = hypeerweb.getNode(15);
			
			System.out.println("Node 15 send to node 7: Print out I am....");
			params = SendVisitor.createInitialParameters(7);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 15 send to node 1: Print out I am....");
			params = SendVisitor.createInitialParameters(1);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 15 send to node 2: Print out I am....");
			params = SendVisitor.createInitialParameters(2);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 15 send to node 3: Print out I am....");
			params = SendVisitor.createInitialParameters(3);
			start.accept(sendvisitor, params);
			
			System.out.println("Node 15 send to node 31: Print out I am....");
			params = SendVisitor.createInitialParameters(31);
			start.accept(sendvisitor, params);
			
			//Delete Tests
			hypeerweb.clear();
	    	System.out.println("Created Size 8 hypeercube");
	    	createHyPeerWebWith(8);
			
			//before delete, save your oldnode
			for(int a = 0; a< hypeerweb.size(); a++){
				System.out.println("Contents: oldnode: " + hypeerweb.getNode(a).contents.get("oldnode"));
			}
			
			
			BroadcastVisitor broadcastvisitor = new BroadcastVisitor() {	
				@Override
				protected void operation(Node node, Parameters parameters) {
					System.out.println("setting my content : oldnode = this.id");
					node.contents.set("oldnode", node.getWebIdValue());
				}
			};

			System.out.println("Node 0 broadcast: set secret in contents to parameters source");
			params = BroadcastVisitor.createInitialParameters();
			hypeerweb.getNode(0).accept(broadcastvisitor, params);
			
			
			for(int a = 0; a< hypeerweb.size(); a++){
				System.out.println("I am " + hypeerweb.getNode(a).getWebIdValue() + " , Contents: oldnode: " + hypeerweb.getNode(a).contents.get("oldnode"));
			}

			// Delete you!
			for(int a = 0; a< hypeerweb.size(); a++){
				System.out.println("I am alive: "+ hypeerweb.getNode(a).getWebIdValue());
			}
			
			sendvisitor = new SendVisitor() {	
				@Override
				protected void targetOperation(Node node, Parameters parameters) {
					node.removeFromHyPeerWeb();
				}
			};
			
			System.out.println("Node 0 send to 5, delete yourself");
			params = SendVisitor.createInitialParameters(5);
			hypeerweb.getNode(0).accept(sendvisitor, params);
			
			
			for(int a = 0; a< hypeerweb.size(); a++){
				System.out.println("I am " + hypeerweb.getNode(a).getWebIdValue() + " , Contents: oldnode: " + hypeerweb.getNode(a).contents.get("oldnode"));
			}
			
			
		}

//		static private void testPhase3() {
//	        System.out.println("\nTesting Phase 4 Send");
//	        hypeerweb.clear();
//	        errorCount = 0;
//	        int testnum=0;
//	        
//	        boolean insertionError = false;
//	        System.out.print("    ");
//	        
//	        for (int size = HYPEERWEB_SIZE; size >= 2; size--) {
//	            if(VERBOSE) {
//	                System.out.println("Testing Node Insertion on HyPeerWeb of size " + size + "/" + HYPEERWEB_SIZE);
//	            } else {
//	                System.out.print(size + " ");
//	            }
//
//	            for (int deletedNodeId = 0; deletedNodeId < size; deletedNodeId++) {
//	                createHyPeerWebWith(size);
//	                
//	                Node deletionNode = hypeerweb.getNode(deletedNodeId);
//	                deletionNode.removeFromHyPeerWeb();
//	                testnum++;
//	                
//	                for (int i = 0; i < size - 1; i++) {
//	                //	System.out.println("Test#"+ testnum);
//	                	
//	                    Node nodei = hypeerweb.getNode(i);
//	                    SimplifiedNodeDomain simplifiedNodeDomain = nodei.constructSimplifiedNodeDomain();
//	                    ExpectedResult expectedResult = new ExpectedResult(size - 1, i);
//
//	                    if (!simplifiedNodeDomain.equals(expectedResult)) {
//	                        insertionError = true;
//	                        System.out.println("DeletionNode is: "+ deletedNodeId);
//	                        printErrorMessage(size, deletionNode, simplifiedNodeDomain, expectedResult);
//	                        errorCount++;
//	                    }
//	                }
//	            }
//	        }
//	        if(!VERBOSE){
//	            System.out.println();
//	        }
//	        
//	        if (insertionError) {
//	            double decimalPercent = ((double)PHASE_3_TEST_COUNT - (double) errorCount) / (double) PHASE_3_TEST_COUNT;
//	            int integerPercent = (int) (decimalPercent * 100.0d);
//	            System.out.println("Error Count: "+ errorCount);
//	            System.out.println("    Insertion Error: Phase 3 Score = " + integerPercent + "%");
//	        } else {
//	            System.out.println("    No Insertion Errors: Phase 3 Score = 100%");
//	        }
//	    }
	    
//	    private static void printErrorMessage(int size, Node startNode, SimplifiedNodeDomain simplifiedNodeDomain, ExpectedResult expectedResult) {
//	        errorCount++;
//
//	        System.out.println("-------------------------------------------------------------");
//	        System.out.println("INSERTION ERROR when HyPeerWebSize = " + size); // + ", Start Location: " + startNode);
//	        System.out.println("Node Information:");
//	        System.out.println(simplifiedNodeDomain);
//	        System.out.println();
//	        System.out.println("Expected Information");
//	        System.out.println(expectedResult);
//	    }

	    static private void createHyPeerWebWith(int numberOfNodes) {
	        hypeerweb.clear();
	        Node node0 = new Node(0);
	        hypeerweb.addToHyPeerWeb(node0, null);

	        for (int i = 1; i < numberOfNodes; i++) {
	            Node node = new Node(0);
	            node0.addToHyPeerWeb(node);
	        }
	    }
	    
//	    private static final int HYPEERWEB_SIZE = 64;
//	    private static final boolean VERBOSE = false;
	}
